using System;
using System.Collections.Generic;
using System.Text;
using Hack.Authorization.Configuration;
using System.ServiceModel;
using log4net;

namespace Hack.Authorization.Base {
	/// <summary>
	/// Base class for all agents.
	/// </summary>
	public abstract class BaseAgent<T> {

		/// <summary>
		/// Log engine.
		/// </summary>
		private static readonly ILog log = LogManager.GetLogger(typeof(BaseAgent<T>));

		#region Fields
		private IConfiguration configuration;
		#endregion Fields

		#region Constructors
		/// <summary>
		/// Default constructor.
		/// </summary>
		/// <param name="config">Configuration to be assigned to the current configuration.</param>
		public BaseAgent(IConfiguration config) {
			log.Debug("Assigning configuration parameter.");
			this.configuration = config;
		}
		#endregion Constructors		

		#region Properties
		/// <summary>
		/// Configuration being used in this agent.
		/// </summary>
		public IConfiguration Configuration {
			get {
				return configuration;
			}
			set {
				configuration = value;
			}
		}
		#endregion Properties

		#region Abstract Methods
		/// <summary>
		/// Gets the endpoint name for the service of this agent.
		/// </summary>
		/// <returns>Returns the name of the endpoint.</returns>
		protected abstract string GetEndPointName();
		#endregion Abstract Methods

		#region Service Instance
		private T service;

		/// <summary>
		/// Current instance of the service.
		/// </summary>
		public T Service {
			get {
				if (service == null) {
					service = GetServiceInstance(GetEndPointName());
				}

				return service;
			}
		}

		#endregion Service Instance

		#region Methods
		/// <summary>
		/// Gets a new service instance.
		/// </summary>
		/// <param name="endPointConfigurationName">Name of the endpoint 
		/// that this service should use to configure itself.</param>
		/// <returns>Returns the service instance.</returns>
		public T GetServiceInstance(string endPointConfigurationName) {
			log.Debug("Creating dynamic proxy...");
			ChannelFactory<T> factory = new ChannelFactory<T>(endPointConfigurationName);
			log.Debug("Creating dynamic channel...");
			T serv = factory.CreateChannel();
			log.Debug("Service Proxy created successfully.");
			return serv;
		}
		#endregion Methods
	}
}
